﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace WMM.Tapioca.Formula.Aspects
{
    /// <summary>
    /// A unit rule is an aspect rule that addresses the unit aspect and that is expressed
    /// by the <formula:unit> element. 
    /// </summary>
    public class UnitAspect : Aspect
    {
        private XElement element;

        internal XElement Element
        {
            get { return element; }
            set { element = value; }
        }
        
        private bool augment;

        /// <returns> If a unit rule contains an @augment attribute with a value of true 
        /// then the SAV for the unit rule is determined as usual. If a unit rule contains 
        /// an @augment attribute with a value of false then the SAV is not defined. </returns>
        internal bool Augment
        {
            get { return augment; }
            set { augment = value; }
        }

        private List<MultiplyByAspect> multiplyByAspectFormulas;

        public List<MultiplyByAspect> MultiplyByAspectFormulas
        {
            get { return multiplyByAspectFormulas; }
            set { multiplyByAspectFormulas = value; }
        }

        private List<DivideByAspect> divideByAspectFormulas;

        public List<DivideByAspect> DivideByAspectFormulas
        {
            get { return divideByAspectFormulas; }
            set { divideByAspectFormulas = value; }
        }

        public UnitAspect()
        {

        }

        /// <summary>
        /// Constructor.
        /// </summary>
        public UnitAspect(XElement unitAspect)
        {
            multiplyByAspectFormulas = new List<MultiplyByAspect>();
            divideByAspectFormulas = new List<DivideByAspect>();

            this.Element = unitAspect;

            XElement aspect = unitAspect.Parent;

            if (aspect.Attribute("source") != null)
            {
                this.Source = aspect.Attribute("source").Value;
            }

            if (unitAspect.Attribute("source") != null)
            {
                this.Source = unitAspect.Attribute("source").Value;
            }

            if (unitAspect.Attribute("augment") != null)
            {
                this.Augment = Boolean.Parse(unitAspect.Attribute("augment").Value);
            }
            else // default="true"
            {
                this.Augment = true;
            }

            IEnumerable<XElement> multiplyBys = unitAspect.Elements(formula + "multiplyBy");

            foreach (XElement multiplyBy in multiplyBys)
            {
                multiplyByAspectFormulas.Add(new MultiplyByAspect(multiplyBy));
            }

            IEnumerable<XElement> divideBys = unitAspect.Elements(formula + "divideBy");

            foreach (XElement divideBy in divideBys)
            {
                divideByAspectFormulas.Add(new DivideByAspect(divideBy));
            }
        }
    }
}
